package cn.itsource.pet.service.impl;

import cn.itsource.config.RedisService;
import cn.itsource.org.domain.TShop;
import cn.itsource.org.mapper.ShopMapper;
import cn.itsource.pet.domain.TPet;
import cn.itsource.pet.domain.TSearchMasterMessage;
import cn.itsource.pet.domain.ViewSearchMasterUser;
import cn.itsource.pet.mapper.PetMapper;
import cn.itsource.pet.mapper.SearchMasterMessageMapper;
import cn.itsource.pet.mapper.ViewSearchMasterUserMapper;
import cn.itsource.pet.query.SearchMasterMessageQuery;
import cn.itsource.pet.service.ISearchMasterService;
import cn.itsource.user.domain.TLogininfo;
import cn.itsource.user.domain.TUser;
import cn.itsource.user.mapper.UserMapper;
import cn.itsource.utils.AjaxResult;
import cn.itsource.utils.DistanceUtil;
import cn.itsource.utils.PageList;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.util.BeanUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.Date;
import java.util.List;

@Service
@Transactional
public class SearchMasterServiceImpl implements ISearchMasterService {
    @Autowired
    private SearchMasterMessageMapper searchMasterMessageMapper;
    @Autowired
    private UserMapper userMapper;

    @Autowired
    private ShopMapper shopMapper;

    @Autowired
    private RedisService redisService;

    @Autowired
    private ViewSearchMasterUserMapper viewSearchMasterUserMapper;

    @Autowired
    private PetMapper petMapper;


    @Override
    public AjaxResult publish(TSearchMasterMessage masterMessage, TLogininfo logininfo) {
        //获取当前登录用户的user_id
        //1. 根据Logininfo对象中的数据，到t_user表中查询对应的用户信息（根据username查询）
        Example example = new Example(TUser.class);
        example.and().orEqualTo("username", logininfo.getUsername())
                .orEqualTo("email", logininfo.getUsername())
                .orEqualTo("phone", logininfo.getUsername());
        //这种，只会最多查询出一条数据，如果你查出的多条，一定是数据有问题（脏数据）
        TUser tUser = userMapper.selectOneByExample(example);
        masterMessage.setUserId(tUser.getId());
        //2. 获取最近的门店的shop_id
        TShop shop = calNearestShopId(masterMessage.getAddress());
        masterMessage.setShopId(shop.getId());

        //先将数据保存到表
        //insertSelective作用：如果某个字段前端没有给值，则会使用表中的默认值
        searchMasterMessageMapper.insertSelective(masterMessage);

        return AjaxResult.me();
    }

    /**
     * 这个方法，就是根据发布的宠物寻主信息中，填写的地址，查到最近的门店信息
     *
     * @param mastMessageAddress
     * @return
     */
    private TShop calNearestShopId(String mastMessageAddress) {
        // 1. 将所有本市的门店数据循环出来
        List<TShop> shopList = shopMapper.selectAll();
        //2. 循环比较找出最近的门店
        //假设离我最近的门店是第1个门店
        TShop nearestShop = shopList.get(0);
        for (int i = 0; i < shopList.size(); i++) {
            TShop shop = shopList.get(i);
            Double distance1 = DistanceUtil.calTwoAddressOfDistance(mastMessageAddress, nearestShop.getAddress());
            Double distance2 = DistanceUtil.calTwoAddressOfDistance(mastMessageAddress, shop.getAddress());
            if (distance1 == null || distance2 == null){//如果任何一个值为null，说明地址解析失败，直接跳到 下一次
                continue;
            }
            if (distance2 < distance1) {
                nearestShop = shop;
            }
        }
        //3. 将这个找出的对象返回
        return nearestShop;
    }

    @Override
    public PageList<ViewSearchMasterUser> findPageByParam(SearchMasterMessageQuery query, String token) {
        //根据token查询当前登录的用户信息
        String logininfoJson = redisService.getKeyObjectValue(token, String.class);
        //根据username查询店铺
        Example example = new Example(ViewSearchMasterUser.class);
        //添加的当前登录用户的帐号条件
        if (StringUtils.isNotBlank(logininfoJson)) {//只要它不为空，说明已经是登录状态
            TLogininfo logininfo = JSONObject.parseObject(logininfoJson, TLogininfo.class);
            example.and().orEqualTo("empUsername", logininfo.getUsername())
                    .orEqualTo("empPhone", logininfo.getUsername())
                    .orEqualTo("empEmail", logininfo.getUsername());
        }
        //TODO 后续如果还要添加查询条件，在这里继续补充
        //添加一个state的查询条件
        if (query.getState() != null) {
            example.and().andEqualTo("state", query.getState());
        }
        //进行分页查询条件组装
        PageHelper.startPage(query.getCurrentPage(), query.getPageSize());
        //返回的pageinfo对象就会包含分页查询的总记录条件及当前页的数据
        PageInfo<ViewSearchMasterUser> pageInfo = new PageInfo<>(viewSearchMasterUserMapper.selectByExample(example));


        return new PageList<>(pageInfo.getTotal(), pageInfo.getList());
    }

    @Override
    public AjaxResult shenghe(Long id, Integer state) {
        //1. 数据校验
        if (id == null || state == null) {
            return AjaxResult.error().setMessage("缺少必传参数");
        }
        //2. 更改 寻主表中的当前这数据的状态state从待处理更新为【已处理】
        TSearchMasterMessage searchMasterMessage = new TSearchMasterMessage();
        searchMasterMessage.setId(id);
        searchMasterMessage.setState(state);
        searchMasterMessageMapper.updateByPrimaryKeySelective(searchMasterMessage);

        //3. 当更改为【已处理】后，同时要将t_search_master_message数据，同步一份到t_pet表
        //原因：当门店管理员将用户发布的寻主宠物移交给门店后。对门店而言，宠物就是一件商品。需要对商品进行编辑
        //使用jdk提供的一个API：bean的复制：只要两个不同实体类中，它的属性名是一样的，就可以直接复制属性对应的值
        TPet pet = new TPet();
        //将searchMasterMessage实体类中的属性，复制到Pet实体类中
        TSearchMasterMessage sourceBean = searchMasterMessageMapper.selectByPrimaryKey(id);
        BeanUtils.copyProperties(sourceBean, pet);
        //复制必要属性后，添加需要给默认值的属性
        pet.setCreatetime(new Date());
        pet.setState(TPet.STATE_XIAJIA);
        //别忘了清空复制过来的 主键ID的值
        pet.setId(null);
        //执行添加操作
        petMapper.insertSelective(pet);

        return AjaxResult.me();
    }
}
